﻿using Laboratory.IRepositories.User;
using Laboratory.Entities.User;
using Abp.UI;
using Laboratory.Users.Dto;
using System.Collections.Generic;
using System.Linq;
using AutoMapper;
using System;
using Abp.Linq.Extensions;
using Abp.Application.Services.Dto;

namespace Laboratory.Users
{
    public class UserService : LaboratoryAppServiceBase, IUserService
    {
        private readonly IRoleRepository _roleRep;
        private readonly IMenuRepository _menuRep;
        private readonly IAccountRepository _accountRep;

        public UserService(IRoleRepository role, IMenuRepository menu, IAccountRepository account)
        {
            _roleRep = role;
            _menuRep = menu;
            _accountRep = account;
        }


        #region # 角色操作

        /// <summary>
        /// 创建角色
        /// </summary>
        /// <param name="name">角色名称</param>
        /// <param name="sort">排序</param>
        public void CreateRole(string name, int sort)
        {
            //验证名称是否存在
            if (_roleRep.ExistsName(null, name))
                throw new UserFriendlyException("该角色数据已经存在！");

            Role entity = new Role(name, sort);

            _roleRep.Insert(entity);
        }

        /// <summary>
        /// 修改角色
        /// </summary>
        /// <param name="id">角色Id</param>
        /// <param name="name">角色名称</param>
        /// <param name="sort">排序</param>
        public void UpdateRole(Guid id, string name, int sort)
        {
            //验证名称是否存在
            if (_roleRep.ExistsName(id, name))
                throw new UserFriendlyException("该角色数据已经存在！");

            Role entity = _roleRep.FirstOrDefault(x => x.Id == id);
            entity.Update(name, sort);
            _roleRep.Update(entity);
        }

        /// <summary>
        /// 查询角色集合
        /// </summary>
        /// <returns></returns>
        public IEnumerable<RoleDto> GetRoles()
        {
            IQueryable<Role> models = _roleRep.GetAll();

            IEnumerable<RoleDto> roleDtos = models.ToList().Select(x => x.ToDto());

            return roleDtos;
        }

        /// <summary>
        /// 查询角色
        /// </summary>
        /// <param name="id">角色Id</param>
        /// <returns></returns>
        public RoleDto GetRole(Guid id)
        {
            Role entity = this._roleRep.FirstOrDefault(x => x.Id == id);

            return entity.ToDto();
        }

        #endregion


        #region # 菜单操作

        /// <summary>
        /// 创建菜单
        /// </summary>
        /// <param name="displayName">显示名称</param>
        /// <param name="icon">图标</param>
        /// <param name="order">排序</param>
        /// <param name="url">链接</param>
        /// <param name="parentId">父级Id</param>
        public void CreateMenu(string displayName, string icon, int order, string url, Guid? parentId)
        {
            //验证名称是否存在
            if (_menuRep.ExistsDisplayName(null, displayName, parentId))
                throw new UserFriendlyException("该菜单数据已经存在！");

            //计算深度
            int depth = 0;
            if (parentId != null)
            {
                Menu parentMenu = _menuRep.FirstOrDefault(x => x.Id == parentId);
                if (parentMenu == null)
                    throw new UserFriendlyException("父级菜单不存在！");
                depth = parentMenu.Depth + 1;
            }

            Menu entity = new Menu(displayName, icon, order, url, depth, parentId);
            _menuRep.Insert(entity);
        }

        /// <summary>
        /// 修改菜单
        /// </summary>
        /// <param name="id">菜单Id</param>
        /// <param name="displayName">显示名称</param>
        /// <param name="icon">图标</param>
        /// <param name="order">排序</param>
        /// <param name="url">链接</param>
        /// <param name="parentId">父级Id</param>
        public void UpdateMenu(Guid id, string displayName, string icon, int order, string url, Guid? parentId)
        {
            //验证名称是否存在
            if (_menuRep.ExistsDisplayName(id, displayName, parentId))
                throw new UserFriendlyException("该菜单数据已经存在！");

            //计算深度
            int depth = 0;
            if (parentId != null)
            {
                Menu parentMenu = _menuRep.FirstOrDefault(x => x.Id == parentId);
                if (parentMenu == null)
                    throw new UserFriendlyException("父级菜单不存在！");
                depth = parentMenu.Depth + 1;
            }

            Menu entity = _menuRep.FirstOrDefault(x => x.Id == id);

            entity.Update(displayName, icon, order, url, depth, parentId);

            _menuRep.Update(entity);
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="id">菜单Id</param>
        public void DeleteMenu(Guid id)
        {
            this._menuRep.Delete(id);
        }

        /// <summary>
        /// 分页查询菜单
        /// </summary>
        /// <param name="keyword">关键字</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageCount">页大小</param>
        /// <returns></returns>
        public PagedResultDto<MenuDto> GetMenus(string keyword, int pageIndex, int pageCount)
        {
            IQueryable<Menu> models = _menuRep.GetAll().Where(x => x.DisplayName.Contains(keyword));

            List<Menu> menus = models.OrderBy(x => x.ParentId).ThenBy(x => x.Order).PageBy(pageIndex - 1, pageCount).ToList();

            IEnumerable<MenuDto> menuDtos = menus.Select(x => x.ToDto());

            return new PagedResultDto<MenuDto>(models.Count(), menuDtos.ToList());
        }

        /// <summary>
        /// 查询层级菜单集
        /// </summary>
        /// <returns></returns>
        public IEnumerable<MenuItemDto> GetMenuItems()
        {
            IQueryable<Menu> models = _menuRep.GetAll().OrderBy(x => x.Order);

            IEnumerable<MenuItemDto> menuItems = models.ToList().ToDtos();

            return menuItems;
        }

        /// <summary>
        /// 查询菜单
        /// </summary>
        /// <param name="id">菜单id</param>
        /// <returns></returns>
        public MenuDto GetMenu(Guid id)
        {
            Menu entity = _menuRep.FirstOrDefault(x => x.Id == id);

            return entity.ToDto();
        }

        #endregion


        #region # 账号操作

        /// <summary>
        /// 创建账号
        /// </summary>
        /// <param name="name">昵称</param>
        /// <param name="loginId">登录Id</param>
        /// <param name="password">密码</param>
        /// <param name="remark">备注</param>
        /// <param name="roleId">角色Id</param>
        /// <param name="isEnabled">是否启用</param>
        public void CreateAccount(string name, string loginId, string password, string remark, Guid roleId, bool isEnabled)
        {
            //验证名称是否存在
            if (_accountRep.ExistsName(null, name, loginId))
                throw new UserFriendlyException("该账号数据已经存在！");

            //查找关联角色
            Role role = this._roleRep.FirstOrDefault(x => x.Id == roleId);
            if (role == null)
                throw new UserFriendlyException("角色不存在！");

            Account entity = new Account(name, loginId, password, remark, role);
            entity.SetEnabled(isEnabled);
            _accountRep.Insert(entity);
        }

        /// <summary>
        /// 修改账号
        /// </summary>
        /// <param name="id">账号Id</param>
        /// <param name="name">昵称</param>
        /// <param name="loginId">登录Id</param>
        /// <param name="password">密码</param>
        /// <param name="remark">备注</param>
        /// <param name="roleId">角色Id</param>
        /// <param name="isEnabled">是否启用</param>
        public void UpdateAccount(Guid id, string name, string loginId, string password, string remark, Guid roleId, bool isEnabled)
        {
            //验证名称是否存在
            if (_accountRep.ExistsName(id, name, loginId))
                throw new UserFriendlyException("该账号数据已经存在！");

            //查找关联角色
            Role role = this._roleRep.FirstOrDefault(x => x.Id == roleId);
            if (role == null)
                throw new UserFriendlyException("角色不存在！");


            Account entity = _accountRep.FirstOrDefault(x => x.Id == id);

            entity.Update(name, loginId, password, remark, role);
            entity.SetEnabled(isEnabled);

            _accountRep.Update(entity);
        }

        /// <summary>
        /// 分页查询账号
        /// </summary>
        /// <param name="keyword">关键字</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageCount">页大小</param>
        /// <returns></returns>
        public PagedResultDto<AccountDto> GetAccounts(string keyword, int pageIndex, int pageCount)
        {
            IQueryable<Account> models = _accountRep.GetAll().Where(x => x.Name.Contains(keyword) || x.LoginId.Contains(keyword));

            List<Account> accounts = models.OrderBy(x => x.AddTime).PageBy(pageIndex + 1, pageCount).ToList();

            IEnumerable<AccountDto> menuDtos = accounts.Select(x => x.ToDto());

            return new PagedResultDto<AccountDto>(models.Count(), menuDtos.ToList());
        }

        /// <summary>
        /// 查询账号
        /// </summary>
        /// <param name="id">账号id</param>
        /// <returns></returns>
        public AccountDto GetAccount(Guid id)
        {
            Account entity = _accountRep.FirstOrDefault(x => x.Id == id);

            return entity.ToDto();
        }

        #endregion

    }
}
